/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.web.task.zkex.simple;

import cn.easyplatform.lang.Strings;
import cn.easyplatform.type.FieldVo;
import cn.easyplatform.web.contexts.Contexts;
import cn.easyplatform.web.ext.ComponentBuilder;
import cn.easyplatform.web.ext.Widget;
import cn.easyplatform.web.ext.ocez.OrgChart;
import cn.easyplatform.web.ext.ocez.OrgNode;
import cn.easyplatform.web.task.OperableHandler;
import cn.easyplatform.web.task.event.EventListenerHandler;
import cn.easyplatform.web.task.zkex.ListSupport;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Events;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class OrgChartBuilder extends AbstractQueryBuilder<OrgChart> implements ComponentBuilder, Widget {

    public OrgChartBuilder(OperableHandler mainTaskHandler, OrgChart comp) {
        super(mainTaskHandler, comp);
    }

    public OrgChartBuilder(ListSupport support, OrgChart comp, Component anchor) {
        super(support, comp, anchor);
    }

    @Override
    public Component build() {
//        if (Strings.isBlank(me.getQuery()))
//            throw new EasyPlatformWithLabelKeyException(
//                    "component.property.not.found", "<orgchart>", "query");
        me.setAttribute("$proxy", this);
        if (me.getNodeId() == null)
            me.setNodeId(Contexts.getUser().getOrgId());//显示当前用户所属的机构id

        if (me.isImmediate())
            load();
        if (!Strings.isBlank(me.getEvent()))
            me.addEventListener(Events.ON_DOUBLE_CLICK, new EventListenerHandler(Events.ON_DOUBLE_CLICK,
                    main, me.getEvent(), anchor));
        if (!Strings.isBlank(me.getDndEvent()))
            me.addEventListener(Events.ON_DROP, new EventListenerHandler(Events.ON_DROP,
                    main, me.getDndEvent(), anchor));
        return me;
    }

    @Override
    protected void createModel(List<?> data) {
        //至少长度是4:0表示当前节点id,1表示上级节点id，2表示名称（人或机构),3表示职位（机构主管或地址),4表示头像
        if (!data.isEmpty()) {
            FieldVo[] first = (FieldVo[]) data.remove(0);
            if (first.length < 3)
                return;
            OrgNode root = null;
            if (first.length == 3)
                root = new OrgNode(first[0].getValue().toString(), (String) first[2].getValue());
            else
                root = new OrgNode(first[0].getValue().toString(), (String) first[2].getValue(), (String) first[3].getValue());
            if (first.length > 4 && first[4].getValue() != null) {
                String val = (String) first[4].getValue();
                if (!Strings.isBlank(val)) {
                    if (val.startsWith("$7")) {
                        try {
                            root.setImg("servlets/download?id=" + URLEncoder.encode(val, "utf8"));
                        } catch (UnsupportedEncodingException e) {
                        }
                    } else
                        root.setImg(val);
                }
            }
            me.setHasImage(true);
            //}
            if (me.isLazy())
                root.setRelationship("001");
            Map<Object, OrgNode> map = new HashMap<Object, OrgNode>();
            map.put(root.getId(), root);
            List<OrgNode> pending = new ArrayList<OrgNode>();
            for (Object row : data) {
                FieldVo[] fv = (FieldVo[]) row;
                OrgNode node = null;
                if (fv.length == 3)
                    node = new OrgNode(fv[0].getValue().toString(), (String) fv[2].getValue());
                else
                    node = new OrgNode(fv[0].getValue().toString(), (String) fv[2].getValue(), (String) fv[3].getValue());
                node.setParentKey(fv[1].getValue() == null ? "" : fv[1].getValue().toString());
                if (fv.length > 4 && fv[4].getValue() != null) {
                    String val = (String) fv[4].getValue();
                    if (!Strings.isBlank(val)) {
                        if (val.startsWith("$7")) {
                            try {
                                node.setImg("servlets/download?id=" + URLEncoder.encode(val, "utf8"));
                            } catch (UnsupportedEncodingException e) {
                            }
                        } else
                            node.setImg(val);
                    }
                }
                OrgNode parent = map.get(node.getParentKey());
                if (parent != null) {
                    parent.appendChild(node);
                    if (!me.isLevelColor())
                        node.setClassName(null);
                } else
                    pending.add(node);
                map.put(node.getId(), node);
            }
            Iterator<OrgNode> itr = pending.iterator();
            while (itr.hasNext()) {
                OrgNode node = itr.next();
                OrgNode parent = map.get(node.getParentKey());
                if (parent != null) {
                    parent.appendChild(node);
                    if (!me.isLevelColor())
                        node.setClassName(null);
                    itr.remove();
                }
            }
            if (me.isLazy() && !root.isLeaf())
                travelNode(root.getChildren(), new StringBuilder(3));
            me.setRootNode(root);
            map = null;
            pending = null;
        }
    }

    @Override
    public void reload(Component widget) {
        load();
    }

    private void travelNode(List<OrgNode> children, StringBuilder sb) {
        for (OrgNode node : children) {
            sb.setLength(0);
            sb.append("1");
            sb.append(children.size() > 1 ? "1" : "0");
            sb.append(node.isLeaf() ? "0" : "1");
            node.setRelationship(sb.toString());
            if (!node.isLeaf())
                travelNode(node.getChildren(), sb);
        }
    }
}
